package cloudspace.vm.javassist;

import java.io.File;
import java.io.IOException;
import java.util.List;

import javassist.CannotCompileException;
import javassist.ClassPool;
import javassist.CtClass;
import javassist.Loader;
import javassist.NotFoundException;

import org.zkoss.zk.ui.Executions;
import org.zkoss.zk.ui.WebApp;

/**
 * The javassist loader class loads a javassist configuration and then applies
 * it to loaders. These configuration files are loaded from the config/javassist
 * folder. They are loaded staticly at start. There is also a logger initialized
 * to handle all logging that is needed from javassist classes.
 */
public abstract class JavassistBootloader
{
	/** The ee factory. */
	private static TranslatorProvider eeFactory = TranslatorProvider
			.getExprEditorFactory();
	private static ClassPool proxyPool;

	/**
	 * Adds a config file to the Javassist Loader. These configuration files are
	 * used to load configurable translators on class loaders.
	 * 
	 * @param configFile
	 *            the config file to add to list of loaders
	 */
	public static void addConfigFile(File configFile)
	{
		try
		{
			//Logger.logInfo(configFile.getAbsolutePath());
			eeFactory.addConfigFile(configFile, proxyPool);
		}
		catch (IOException e)
		{
			Logger.logInfo("Bad Configfile:  " + configFile);
			e.printStackTrace();
		}
	}

	/**
	 * This method adds configurable translators to the passed loader. This
	 * translator is created using the loaded configuration files.
	 * 
	 * @param localClassLoader
	 *            the classloader to be translated.
	 * @param localClassPool
	 *            the class pool to find classes required for translations
	 * 
	 * @throws MalformedConfigurationException
	 *             the malformed configuration exception
	 */
	public static void translateClasses(Loader localClassLoader,
			ClassPool localClassPool) throws MalformedConfigurationException
	{
		List<ConfigurableTranslatorLoader> translators = eeFactory.getTranslators();
		for (ConfigurableTranslatorLoader curTranslator : translators)
		{
			try
			{
				localClassLoader.addTranslator(localClassPool, curTranslator);
			}
			catch (CannotCompileException e)
			{
				Logger
						.logInfo("A strange error occured when a translator was registered.");
			}
			catch (NotFoundException e)
			{
				Logger.logInfo("Strange error with Not Found Exception");
			}
		}

	}

	public static String getProxy(String className)
	{

		CtClass proxy = eeFactory.getProxy(className);
		if (proxy != null)
			return proxy.getName();
		return null;
	}

	public static ClassPool getProxyPool()
	{
		return proxyPool;
	}

	static
	{
		String configPath = "";
		proxyPool = new ClassPool();
		try
		{
			if (Executions.getCurrent() != null)
			{
				WebApp app = Executions.getCurrent().getDesktop().getWebApp();

				proxyPool.appendClassPath(app.getRealPath("/WEB-INF/classes"));

				configPath = app.getRealPath("configs/javassist");
			}
			else
			{
				proxyPool.appendClassPath("src");
				configPath = "resources/configs/javassist";
			}
		}
		catch (NotFoundException e)
		{
			e.printStackTrace();
		}
		proxyPool.appendSystemPath();
		Logger.registerLogger("BCRError.log");
		File configDir = new File(configPath);
		File[] directoryContents = configDir.listFiles();
		for (File configFile : directoryContents)
		{
			if (configFile.getName().endsWith(".conf"))
				JavassistBootloader.addConfigFile(configFile);
		}

	}

}
